/**
 * useReducer
 *   换一个方式来初始化 state 和 修改 state 。
 *
 * 理解：什么是 reducer
 *    1. 是个函数
 *    2. 是个纯函数
 *    3. 接受两个参数
 *        state     上次的state数据
 *        action    一个动作，描述了如何去修改state
 *                  { type: 'add', payload: 其他数据 }
 * 理解：什么是纯函数
 *    1. 确定的输入，产生确定的输出，与执行次数、时间无关
      2. 不产生副作用（额外关注一个点：不能去修改入参）

   语法：const [state, dispatch] = useReducer(reducer, initialState);

        1. 第一个参数，就是一个纯函数，里面根据传递的 action 不同来返回全新的 state
        2. 第二个 initialState ，就是初始化 state 数据

        返回的数组的第一项就是一个 state 数据
        返回的数组的第二项就是一个 函数，调用这个函数，会触发 reducer 的执行，且需要传递一个 action
 */

// add 是个纯函数
// function add(x) {
//   return x + 1;
// }
// add(1) => 2
// add(1) => 2
// add(1) => 2

// // Math.random 不是纯函数
// Math.random(1) => 未知1
// Math.random(1) => 未知2

// 这个add 不是个纯函数，有未知的依赖 y
// let y = 10;
// function add(x) {
//   return x + y;
// }
// add(1) => 11
// add(1) => 11
// y = 20
// add(1) => 21

// reducer 不是个纯函数，应为里面修改了入参 obj
// let obj = { name: "zhagsan", age: 18 };
// function reducer(state, action) {
//   if (action.type === "changeName") {
//     state.name = action.payload;
//     return state;
//   } else {
//     return state;
//   }
// }
// reducer(obj, { type: "changeName", payload: "里斯" });

import React, { useReducer } from "react";
import ReactDOM from "react-dom/client";

function App() {
  const [state, dispatch] = useReducer(
    (state, action) => {
      // 要根据 action 的不同来返回一份全新的 state 数据，来重新渲染组件
      // 这个函数（reducer）在什么时候执行：
      //    当调用 dispatch() 时执行
      // console.log("state", state);
      // console.log("action", action);
      if (action.type === "xxx") {
        // 不报错，但是没有效果
        // state.name = action.payload;
        // return state;
        // 必须返回全新的state
        return {
          ...state,
          name: action.payload,
        };
      } else if (action.type === "yyy") {
        return {
          ...state,
          age: action.payload,
        };
      } else {
        // 如果动作不满足上面两个条件的话，就直接返回上一次额 state
        return {
          ...state,
        };
      }
    },
    {
      name: "张三",
      age: 18,
    }
  );

  // console.log(state);
  // console.log(dispatch);

  function handleClick() {
    dispatch({ type: "xxx", payload: "里斯" });
  }

  return (
    <div>
      <h1 id="h1">
        App - {state.name} - {state.age}
      </h1>
      <button onClick={handleClick}>修改 name</button>
      <button
        onClick={() => {
          dispatch({ type: "yyy", payload: 100 });
        }}
      >
        修改 age
      </button>
    </div>
  );
}

const root = ReactDOM.createRoot(document.querySelector("#root"));
root.render(<App />);
